#include <spi_sim.h>

unsigned char hw_spi_rw_sim(const spi_io_def *dat, unsigned char data)
{
    char buf, readbyte, i;
    //    digitalWrite(dat->cs, 0);
    delayMicroseconds(dat->delay);
    for (i = 0; i < 8; i++)
    {

        readbyte = readbyte << 1;
        buf = (data >> (7 - i)) & 0x1; //MSB???,LSB???
        if (dat->cpha)
            digitalWrite(dat->mosi, buf); //?????????????DIN
        else if (digitalRead(dat->miso))
        {
            readbyte++;
        }

        delayMicroseconds(dat->delay);
        digitalWrite(dat->clk, !dat->cpol); //?????????????

        delayMicroseconds(dat->delay);

        if (!dat->cpha)
            digitalWrite(dat->mosi, buf); //?????????????DIN
        else if (digitalRead(dat->miso))
        {
            readbyte++;
        }
        delayMicroseconds(dat->delay);
        digitalWrite(dat->clk, dat->cpol);

        delayMicroseconds(dat->delay);
    }

    //    digitalWrite(dat->cs, 1);
    delayMicroseconds(dat->delay);
    return readbyte;
}

#if defined(RT_THREAD) || defined(USE_HAL_DRIVER)
unsigned char hw_spi_rw_sim_rt(const spi_io_def *dat, unsigned char data)
{
    char buf, readbyte, i;
    //    digitalWrite(dat->cs, 0);
    //    delayMicroseconds(dat->delay);
    readbyte = 0;
    for (i = 0; i < 8; i++)
    {

        readbyte = readbyte << 1;
        buf = (data >> (7 - i)) & 0x1; //MSB???,LSB???
        if (!dat->cpha)
        {
            digitalWrite(dat->mosi, buf); //?????????????DIN
        }

        delayMicroseconds(dat->delay);

        if (!dat->cpha && digitalRead(dat->miso))
        {
            readbyte++;
        }
        digitalWrite(dat->clk, !dat->cpol); //?????????????

        //#ifdef USE_HAL_DRIVER
        //        vTaskDelay(dat->delay);
        //#else
        //        delayMicroseconds(dat->delay);
        //#endif

        if (dat->cpha)
        {
            digitalWrite(dat->mosi, buf); //?????????????DIN
        }

        delayMicroseconds(dat->delay);

        if (dat->cpha && digitalRead(dat->miso))
        {
            readbyte++;
        }
        digitalWrite(dat->clk, dat->cpol);

        // #ifdef USE_HAL_DRIVER
        //         vTaskDelay(dat->delay);
        // #else
        //         delayMicroseconds(dat->delay);
        // #endif
    }
    //    digitalWrite(dat->cs, 1);
    //    delayMicroseconds(dat->delay);

    return readbyte;
}
#endif
#ifndef MCU_TINY

int spi_io_read_word(const spi_io_def *dat)
{
    unsigned short buf = 0, temp;
    volatile char i, j;
    digitalWrite(dat->mosi, 0);
    digitalWrite(dat->clk, 1);
    for (i = 0; i < 16; i++)
    {
        buf = buf << 1;
        for (j = 0; j < 200; j++)
            ; //200ns
        digitalWrite(dat->clk, 1);
        for (j = 0; j < 200; j++)
            ;

        temp = digitalRead(dat->miso);
        buf |= temp;
        for (j = 0; j < 200; j++)
            ; //200ns
        digitalWrite(dat->clk, 0);
    }
    //      digitalWrite(dat->clk, 1);
    buf &= 0xffff;
    return (buf);
}
#endif

void hw_spi_sim_init(const spi_io_def *dat)
{
    pinMode(dat->cs, OUTPUT);
    pinMode(dat->mosi, OUTPUT);
    pinMode(dat->clk, OUTPUT);
    pinMode(dat->miso, INPUT_PULLUP);
    digitalWrite(dat->clk, 0);
    digitalWrite(dat->cs, 1);
    digitalWrite(dat->mosi, 1);
}
void hw_spi_sim_uninit(const spi_io_def *dat) {
    pinMode(dat->cs, INPUT_PULLDOWN);
    pinMode(dat->mosi, INPUT_PULLDOWN);
    pinMode(dat->clk, INPUT_PULLDOWN);
    pinMode(dat->miso, INPUT_PULLDOWN);
}